package aliens
{
	/**
	 * ...
	 * @author Jeroen Gildemacher
	 */
	import aliens.*
	import caves.points.ResourcePoint;
	import caves.points.SpacePoint;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import screen.GameScreen;
	import map.MapSource;
	import aliens.tasks.*;
	import aliens.tasks.subTasks.*;

	import aliens.tasks.TaskCreator;
	import utils.*;
	
	public class AlienController
	{
		private var mapSource:MapSource;
		private var _aliens:Vector.<Alien> = new Vector.<Alien>;
		private var _gameScreen:GameScreen;
		
		
		public function AlienController(mp:MapSource, gameScreen:GameScreen)
		{
			this._gameScreen = gameScreen;
			this.mapSource = mp;
			TaskCreator.map = mapSource;
		}
		
		public function createAlien(type:String, place:Point):void
		{
			var alien:Alien;
			var subTasks:Vector.<SubTask>= new Vector.<SubTask>;
			switch (type)
			{
				case Alien.BASE_ALIEN: 
					alien = new aliens.BaseAlien(this);
					alien.home = new Point;
					alien.home.x = place.x;
					alien.home.y = 50;
					alien.mapY = place.y;
					alien.mapX = place.x;
					subTasks.push(new ExploreSubTask(getExploreDirection(alien.getMapPos())));
					alien.currentTask = new aliens.tasks.ExploreTask(subTasks);
					_aliens.push(alien);
					break;
			}
		}
		
		public function moveAliens():void
		{
			var alien:aliens.Alien;
			var d:int;
			for (var i:int; i < _aliens.length; i++)
			{
				alien = _aliens[i];
				checkTaskStatus(alien);
					d = DirectionHelper.getBestDirection(new Point(alien.mapX, alien.mapY), alien.currentTask.subTasks[alien.currentSubTask].target);
					if (d == DirectionHelper.HERE)
					{
						alien.getNextSubTask();
					}
					alien.mapX += DirectionHelper.getDx(d);
					alien.mapY += DirectionHelper.getDy(d);
					if (alien.mapX < 0)
						alien.mapX = 0;
					if (alien.mapX > 1000)
						alien.mapX = 1000;
					if (alien.mapY < 0)
						alien.mapY = 0;
					if (alien.mapY > 1000)
						alien.mapY = 1000;
				
			}
		}
		
		public function getNewTask(p_alien:Alien):void
		{
			if (canBuild(Alien.BASE_ALIEN)) {
				trace("can build");
			} else {
				if (p_alien.currentTask.subTasks[p_alien.currentSubTask] is ExploreSubTask) {
					p_alien.currentTask.subTasks[p_alien.currentSubTask].target = getExploreDirection(p_alien.getMapPos()); 
				}
			}
		}
		
		private function checkTaskStatus(alien:Alien):void
		{
			var i:int = alien.currentSubTask;
			var target:Point = alien.currentTask.subTasks[i].target;
			var c:int;
			if (target != null)
			{
				if (alien.mapX == target.x && alien.mapY == target.y)
				{
					if (alien.currentTask.subTasks[i] is ExploreSubTask)
					{
						mapSource.explorePoint(alien.getMapPos());
						alien.getNextSubTask();
					}

				}
			}
			else
			{
				if (alien.currentTask.subTasks[i] is PauseSubTask)
				{
					PauseSubTask(alien.currentTask.subTasks[i]).nrPauseTick--;
					if (PauseSubTask(alien.currentTask.subTasks[i]).nrPauseTick == 0)
					{
						alien.getNextSubTask();
					}
				}
			}
		}
		
		public function getAliensInRectangle(r:Rectangle):Vector.<Alien>
		{
			var o:Object = new Object;
			o.x = r.x;
			o.y = r.y;
			o.right = r.right;
			o.bottom = r.bottom;
			var filterFunction:Function = function(element:Alien, index:int, v:Vector.<Alien>):Boolean
			{
				return (element.mapX >= this.x && element.mapX <= this.right && element.mapY >= this.y && element.mapY <= this.bottom);
			}
			
			return _aliens.filter(filterFunction, o);
		}
		
		public function get aliens():Vector.<Alien>
		{
			return _aliens;
		}
		
		public function set aliens(value:Vector.<Alien>):void
		{
			_aliens = value;
		}
		
		private function getExploreDirection(p:Point):Point {
			if (mapSource.canMoveToPoint(below(p))) {
				return below(p);
			} else 			if (mapSource.canMoveToPoint(toTheRight(p))) {
				return toTheRight(p);
			} else 			if (mapSource.canMoveToPoint(toTheLeft(p))) {
				return toTheLeft(p);
			} else 			if (mapSource.canMoveToPoint(above(p))) {
				return above(p);
			} 
			return null;
		}
		
		private function canBuild(type:String, alien:Alien):Boolean {
			var v:Vector.<ResourcePoint> = mapSource.getResourceCombo(BaseAlien.buildingBlocks);
			if (v != null) {
				alien.lockedPoints = new Vector.<SpacePoint>;
				for each(var r:ResourcePoint in v) {
					r.locked = true;
					alien.lockedPoints.push(r);
				}
				alien.target
			}
			
			//var blocks:Vector.<int>= new Vector.<int>; 
			//switch (type) {
			//	case Alien.BASE_ALIEN:
			//		blocks = BaseAlien.buildingBlocks;
			//		break;
			//}
			//for (var i:int = 0 ; i < blocks.length; i++) {
			//	if (mapSource.getNrResource(i) < blocks[i] ){
			//		return false;
			//	}
			//}
			return false;
		}
		
	}

}